package com.baosight.innerinterface.service;

/**
 * Title:  产生表的序列号
 * Desc :  表的主键为整形字段 或 35/32/16/20位 字符
 *  
 */
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.SecureRandom;
import java.util.Hashtable;

public class TablePk {
	private TablePk(){
		
	}
	private static TablePk uniqueInstance = null; //唯一性实例
	
	@SuppressWarnings("unused")
	private Hashtable<String, String> hashKey = new Hashtable<String, String>(); //存放表的主键值
	private static String hexServerIP = null; //ServerIp地址
	private static final SecureRandom seeder = new SecureRandom(); //随机数

//	private String DealWithhashKey(String name, String value, String operation) {
//		name = name.trim();
//		value = value.trim();
//		operation = operation.trim();
//
//		if (operation.equals("read")) {
//
//			if (hashKey.get(name) == null) {
//				return null;
//			} else {
//				return (String) hashKey.get(name);
//			}
//
//		} else if (operation.equals("update")) {
//
//			int intKeyValue = Integer.parseInt((String) hashKey.get(name));
//			intKeyValue++;
//			hashKey.put(name, String.valueOf(intKeyValue));
//			return String.valueOf(intKeyValue);
//
//		} else if (operation.equals("initialization")) {
//
//			hashKey.put(name, value);
//			return value;
//
//		} else {
//			return "error";
//		}
//	}

	/**
	 * 清空数值型主键缓存
	 * 
	 */
	public synchronized void RefreshKey() {
		hashKey = new Hashtable<String, String>();
	}

	/**
	 * 得到表的字符型主键(32位)
	 * 
	 * @return String 表的字符型主键(32位)
	 * 
	 */
	public synchronized final String getNextValue(String tbName) {
		StringBuffer tmpBuffer = new StringBuffer(16);
		if (hexServerIP == null) {
			InetAddress localInetAddress = null;
			try {
				localInetAddress = InetAddress.getLocalHost();
			} catch (UnknownHostException uhe) {
				uhe.printStackTrace();
				return null;
			}
			byte serverIP[] = localInetAddress.getAddress();
			hexServerIP = hexFormat(getInt(serverIP), 8);
		}
		String hashcode = hexFormat(System.identityHashCode(tbName), 8);
		tmpBuffer.append(hexServerIP);
		tmpBuffer.append(hashcode);
		long timeNow = System.currentTimeMillis();
		int timeLow = (int) timeNow & 0xffffffff;
		int node = seeder.nextInt();
		StringBuffer guid = new StringBuffer(32);
		guid.append(hexFormat(timeLow, 8));
		guid.append(tmpBuffer.toString());
		guid.append(hexFormat(node, 8));
		return guid.toString();
	}

	/**
	 * 得到表的字符型主键(35位) 留3位位置码,待业务扩展用
	 * 
	 * @return String 表的字符型主键(35位)
	 * 
	 */
	public synchronized final String getNextValue35(String tbName, String local) {
		if (local.length() > 3) {
			local = local.substring(0, 3);
		}
		return getNextValue(tbName);
	}

	public synchronized final String getNextValue35(String tbName) {
		return tbName.substring(tbName.length() - 3) + getNextValue(tbName);
	}

	/**
	 * 得到表的字符型主键(16位)
	 * 
	 * @return String 表的字符型主键(16位)
	 */
	public synchronized final String getNextValue16() {
		long timeNow = System.currentTimeMillis();
		int timeLow = (int) timeNow & 0xffffffff;
		int node = seeder.nextInt();
		StringBuffer guid = new StringBuffer(16);
		guid.append(hexFormat(timeLow, 8));
		guid.append(hexFormat(node, 8));
		return guid.toString();
	}

	/**
	 * 得到表的字符型主键(20位)
	 * 
	 * @return String 表的字符型主键(20位)
	 */
	public synchronized final String getNextValue20() {
		long timeNow = System.currentTimeMillis();
		String addnum = String.valueOf(timeNow);
		if (addnum.length() > 4) {
			addnum = addnum.substring(addnum.length() - 4);
		}
		return addnum + getNextValue16();
	}

	private static int getInt(byte bytes[]) {
		int i = 0;
		int j = 24;
		for (int k = 0; j >= 0; k++) {
			int l = bytes[k] & 0xff;
			i += l << j;
			j -= 8;
		}

		return i;
	}

	private static String hexFormat(int i, int j) {
		String s = Integer.toHexString(i);
		return padHex(s, j) + s;
	}

	private static String padHex(String s, int i) {
		StringBuffer tmpBuffer = new StringBuffer();
		if (s.length() < i) {
			for (int j = 0; j < i - s.length(); j++)
				tmpBuffer.append('0');

		}
		return tmpBuffer.toString();
	}

	/**
	 * 句柄，供调用
	 */
	public synchronized static TablePk getInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new TablePk();
		}
		return uniqueInstance;
	}
}
